/*
**  Copyright (c) 2014 Michael Liu(michael.liu.point@gmail.com).
**
**  Project: Gateway Unified Management Platform
**  File:      dpapi.c
**  Author:  Michael
**  Date:    06/27/2014
**
**  Purpose:
**     Data Path Management API implement.
*/

/* Include files. */

#include "cmapi.h"

/* Macro constant definitions. */

/* Type definitions. */

/* Local function declarations. */

static e_ret wlancli_do_scan_aps(tcm_session * session, const char *name, e_bool start);
static e_ret dp_if_setlinkcfg(tcm_session * session, const char *name, tmask * mask, void *linkcfg, int linkcfg_size);
static e_ret dp_if_getlinkcfg(tcm_session * session, const char *name, void **linkcfg, int *linkcfg_size);
static e_ret dp_if_do_getlinkstatus(tcm_session * session, const char *name, e_bool query, void **linkstatus);
static e_ret dp_cmn_opt_dev_optmode(tcm_session * session, unsigned char *mode, e_bool set);
static e_ret dp_cmn_opt_dev_countryregion(tcm_session * session, unsigned int *country_num, e_bool set);

/* Macro API definitions. */

/* Global variable declarations. */

e_ret dp_if_setlinkcfg(tcm_session * session, const char *name, tmask * mask, void *linkcfg, int linkcfg_size)
{
	e_ret ret;
	int req_size;
	int rsp_size;
	void **tmp;
	tcm_req_body *req;
	tcm_rsp_body *rsp;
	tcm_dp_req_body *dp_req;
	tcm_dp_rsp_body *dp_rsp;
	tcm_dp_if_req_body *dp_if_req;
	tcm_dp_if_rsp_body *dp_if_rsp;

	req_size = sizeof(*req) + sizeof(*dp_req) + sizeof(*dp_if_req) + linkcfg_size;
	req = malloc(req_size);
	if (req == NULL) {
		cmapi_error("malloc(%d) failed, err: %d,[%s]\n", req_size, errno, strerror(errno));
		return (eRET_NO_RESOURCE);
	}
	memset(req, 0, req_size);
	req->module = eCM_MODULE_DATA_PATH;
	req->req_body_len = sizeof(*dp_req) + sizeof(*dp_if_req) + linkcfg_size;

	dp_req = (tcm_dp_req_body *) req->mod_req_body;
	dp_req->submod = eDP_SUB_MOD_DP_IF;
	dp_if_req = (tcm_dp_if_req_body *) dp_req->body;

	dp_if_req->mask = *mask;
	dp_if_req->opt = eDP_IF_METHOD_SET_LINKCFG;
	str_safe_cpy(dp_if_req->name, name, DP_IF_NAMESIZE - 1);

	memcpy(dp_if_req->body, linkcfg, linkcfg_size);

	rsp = NULL;
	rsp_size = 0;
	tmp = (void *)&rsp;
	ret = cmapi_require(session, 1, req, req_size, tmp, &rsp_size);
	free(req);
	if (rsp != NULL) {
		if (rsp->rsp_body_len != 0) {
			dp_rsp = (tcm_dp_rsp_body *) rsp->mod_rsp_body;
			dp_if_rsp = (tcm_dp_if_rsp_body *) dp_rsp->body;
			*mask = dp_if_rsp->mask;
		}

		if (rsp->ret != eRET_SUCCESS) {
			ret = rsp->ret;
		}
		free(rsp);
	} else {
		memset(mask, 0, sizeof(*mask));
	}

	return (ret);

}

e_ret dp_if_getlinkcfg(tcm_session * session, const char *name, void **linkcfg, int *linkcfg_size)
{
	e_ret ret;
	int req_size;
	int rsp_size;
	void *cfg;
	int cfg_size;
	void **tmp;
	tcm_req_body *req;
	tcm_rsp_body *rsp;
	tcm_dp_req_body *dp_req;
	tcm_dp_rsp_body *dp_rsp;
	tcm_dp_if_req_body *dp_if_req;
	tcm_dp_if_rsp_body *dp_if_rsp;

	*linkcfg = cfg = NULL;
	*linkcfg_size = cfg_size = 0;
	req_size = sizeof(*req) + sizeof(*dp_req) + sizeof(*dp_if_req);
	req = malloc(req_size);
	if (req == NULL) {
		cmapi_error("malloc(%d) failed, err: %d,[%s]\n", req_size, errno, strerror(errno));
		return (eRET_NO_RESOURCE);
	}
	memset(req, 0, req_size);
	req->module = eCM_MODULE_DATA_PATH;
	req->req_body_len = sizeof(*dp_req) + sizeof(*dp_if_req);

	dp_req = (tcm_dp_req_body *) req->mod_req_body;
	dp_req->submod = eDP_SUB_MOD_DP_IF;
	dp_if_req = (tcm_dp_if_req_body *) dp_req->body;

	dp_if_req->opt = eDP_IF_METHOD_GET_LINKCFG;
	str_safe_cpy(dp_if_req->name, name, DP_IF_NAMESIZE - 1);

	rsp = NULL;
	rsp_size = 0;
	tmp = (void *)&rsp;
	ret = cmapi_require(session, 1, req, req_size, tmp, &rsp_size);
	free(req);
	if (rsp != NULL) {
		if (rsp->ret != eRET_SUCCESS) {
			ret = rsp->ret;
		}

		if (rsp->rsp_body_len != 0) {
			dp_rsp = (tcm_dp_rsp_body *) rsp->mod_rsp_body;
			dp_if_rsp = (tcm_dp_if_rsp_body *) dp_rsp->body;
			cfg_size = rsp->rsp_body_len - sizeof(*dp_rsp) - sizeof(*dp_if_rsp);
			if (cfg_size > 0) {
				cfg = malloc(cfg_size);
				if (cfg == NULL) {
					cfg_size = 0;
					ret = eRET_NO_RESOURCE;
				} else {
					memcpy(cfg, dp_if_rsp->body, cfg_size);
				}
			}
		}
		free(rsp);
	}

	*linkcfg = cfg;
	*linkcfg_size = cfg_size;

	return (ret);

}

e_ret dp_if_setnetcfg(tcm_session * session, const char *name, tmask * mask, void *netcfg, int netcfg_size)
{
	e_ret ret;
	int req_size;
	int rsp_size;
	void **tmp;
	tcm_req_body *req;
	tcm_rsp_body *rsp;
	tcm_dp_req_body *dp_req;
	tcm_dp_rsp_body *dp_rsp;
	tcm_dp_if_req_body *dp_if_req;
	tcm_dp_if_rsp_body *dp_if_rsp;

	req_size = sizeof(*req) + sizeof(*dp_req) + sizeof(*dp_if_req) + netcfg_size;
	req = malloc(req_size);
	if (req == NULL) {
		cmapi_error("malloc(%d) failed, err: %d,[%s]\n", req_size, errno, strerror(errno));
		return (eRET_NO_RESOURCE);
	}
	memset(req, 0, req_size);
	req->module = eCM_MODULE_DATA_PATH;
	req->req_body_len = sizeof(*dp_req) + sizeof(*dp_if_req) + netcfg_size;

	dp_req = (tcm_dp_req_body *) req->mod_req_body;
	dp_req->submod = eDP_SUB_MOD_DP_IF;
	dp_if_req = (tcm_dp_if_req_body *) dp_req->body;

	dp_if_req->mask = *mask;
	dp_if_req->opt = eDP_IF_METHOD_SET_NETCFG;
	str_safe_cpy(dp_if_req->name, name, DP_IF_NAMESIZE - 1);

	memcpy(dp_if_req->body, netcfg, netcfg_size);

	rsp = NULL;
	rsp_size = 0;
	tmp = (void *)&rsp;
	ret = cmapi_require(session, 1, req, req_size, tmp, &rsp_size);
	free(req);
	if (rsp != NULL) {
		if (rsp->rsp_body_len != 0) {
			dp_rsp = (tcm_dp_rsp_body *) rsp->mod_rsp_body;
			dp_if_rsp = (tcm_dp_if_rsp_body *) dp_rsp->body;
			*mask = dp_if_rsp->mask;
		}

		if (rsp->ret != eRET_SUCCESS) {
			ret = rsp->ret;
		}
		free(rsp);
	} else {
		memset(mask, 0, sizeof(*mask));
	}

	return (ret);

}

e_ret dp_if_getnetcfg(tcm_session * session, const char *name, void **netcfg, int *netcfg_size)
{
	e_ret ret;
	int req_size;
	int rsp_size;
	void *cfg;
	int cfg_size;
	void **tmp;
	tcm_req_body *req;
	tcm_rsp_body *rsp;
	tcm_dp_req_body *dp_req;
	tcm_dp_rsp_body *dp_rsp;
	tcm_dp_if_req_body *dp_if_req;
	tcm_dp_if_rsp_body *dp_if_rsp;

	*netcfg = cfg = NULL;
	*netcfg_size = cfg_size = 0;
	req_size = sizeof(*req) + sizeof(*dp_req) + sizeof(*dp_if_req);
	req = malloc(req_size);
	if (req == NULL) {
		cmapi_error("malloc(%d) failed, err: %d,[%s]\n", req_size, errno, strerror(errno));
		return (eRET_NO_RESOURCE);
	}
	memset(req, 0, req_size);
	req->module = eCM_MODULE_DATA_PATH;
	req->req_body_len = sizeof(*dp_req) + sizeof(*dp_if_req);

	dp_req = (tcm_dp_req_body *) req->mod_req_body;
	dp_req->submod = eDP_SUB_MOD_DP_IF;
	dp_if_req = (tcm_dp_if_req_body *) dp_req->body;

	dp_if_req->opt = eDP_IF_METHOD_GET_NETCFG;
	str_safe_cpy(dp_if_req->name, name, DP_IF_NAMESIZE - 1);

	rsp = NULL;
	rsp_size = 0;
	tmp = (void *)&rsp;
	ret = cmapi_require(session, 1, req, req_size, tmp, &rsp_size);
	free(req);
	if (rsp != NULL) {
		if (rsp->ret != eRET_SUCCESS) {
			ret = rsp->ret;
		}

		if (rsp->rsp_body_len != 0) {
			dp_rsp = (tcm_dp_rsp_body *) rsp->mod_rsp_body;
			dp_if_rsp = (tcm_dp_if_rsp_body *) dp_rsp->body;
			cfg_size = rsp->rsp_body_len - sizeof(*dp_rsp) - sizeof(*dp_if_rsp);
			if (cfg_size > 0) {
				cfg = malloc(cfg_size);
				if (cfg == NULL) {
					cfg_size = 0;
					ret = eRET_NO_RESOURCE;
				} else {
					memcpy(cfg, dp_if_rsp->body, cfg_size);
				}
			}
		}
		free(rsp);
	}

	*netcfg = cfg;
	*netcfg_size = cfg_size;

	return (ret);

}

e_ret dp_if_getnetstatus(tcm_session * session, const char *name, void **netstatus, int *netstatus_size)
{
	e_ret ret;
	int req_size;
	int rsp_size;
	void *status;
	int status_size;
	void **tmp;
	tcm_req_body *req;
	tcm_rsp_body *rsp;
	tcm_dp_req_body *dp_req;
	tcm_dp_rsp_body *dp_rsp;
	tcm_dp_if_req_body *dp_if_req;
	tcm_dp_if_rsp_body *dp_if_rsp;

	*netstatus = status = NULL;
	*netstatus_size = status_size = 0;
	req_size = sizeof(*req) + sizeof(*dp_req) + sizeof(*dp_if_req);
	req = malloc(req_size);
	if (req == NULL) {
		cmapi_error("malloc(%d) failed, err: %d,[%s]\n", req_size, errno, strerror(errno));
		return (eRET_NO_RESOURCE);
	}
	memset(req, 0, req_size);
	req->module = eCM_MODULE_DATA_PATH;
	req->req_body_len = sizeof(*dp_req) + sizeof(*dp_if_req);

	dp_req = (tcm_dp_req_body *) req->mod_req_body;
	dp_req->submod = eDP_SUB_MOD_DP_IF;
	dp_if_req = (tcm_dp_if_req_body *) dp_req->body;

	dp_if_req->opt = eDP_IF_METHOD_GET_NET_STATUS;
	str_safe_cpy(dp_if_req->name, name, DP_IF_NAMESIZE - 1);

	rsp = NULL;
	rsp_size = 0;
	tmp = (void *)&rsp;
	ret = cmapi_require(session, 1, req, req_size, tmp, &rsp_size);
	free(req);
	if (rsp != NULL) {
		if (rsp->ret != eRET_SUCCESS) {
			ret = rsp->ret;
		}

		if (rsp->rsp_body_len != 0) {
			dp_rsp = (tcm_dp_rsp_body *) rsp->mod_rsp_body;
			dp_if_rsp = (tcm_dp_if_rsp_body *) dp_rsp->body;
			status_size = rsp->rsp_body_len - sizeof(*dp_rsp) - sizeof(*dp_if_rsp);
			if (status_size > 0) {
				status = malloc(status_size);
				if (status == NULL) {
					status_size = 0;
					ret = eRET_NO_RESOURCE;
				} else {
					memcpy(status, dp_if_rsp->body, status_size);
				}
			}
		}
		free(rsp);
	}

	*netstatus = status;
	*netstatus_size = status_size;

	return (ret);

}

e_ret wlancli_do_scan_aps(tcm_session * session, const char *name, e_bool start)
{
	e_ret ret;
	tmask mask;
	int req_size;
	int rsp_size;
	void **tmp;
	tcm_req_body *req;
	tcm_rsp_body *rsp;
	tcm_dp_req_body *dp_req;
	tcm_dp_rsp_body *dp_rsp;
	tcm_dp_if_req_body *dp_if_req;
	tcm_dp_if_rsp_body *dp_if_rsp;

	/* Set cancel and query to start scan. */
	memset(&mask, 0, sizeof(mask));
	if (start) {
		/* Start scan. */
		mask_set_bit(mask.mask[0], eWLAN_LINKSTAT_MASK0_CANCEL);
		mask_set_bit(mask.mask[0], eWLAN_LINKSTAT_MASK0_QUERY);
	} else {
		/* Stop scan. */
		mask_set_bit(mask.mask[0], eWLAN_LINKSTAT_MASK0_CANCEL);
	}

	req_size = sizeof(*req) + sizeof(*dp_req) + sizeof(*dp_if_req);
	req = malloc(req_size);
	if (req == NULL) {
		cmapi_error("malloc(%d) failed, err: %d,[%s]\n", req_size, errno, strerror(errno));
		return (eRET_NO_RESOURCE);
	}
	memset(req, 0, req_size);
	req->module = eCM_MODULE_DATA_PATH;
	req->req_body_len = sizeof(*dp_req) + sizeof(*dp_if_req);

	dp_req = (tcm_dp_req_body *) req->mod_req_body;
	dp_req->submod = eDP_SUB_MOD_DP_IF;
	dp_if_req = (tcm_dp_if_req_body *) dp_req->body;

	dp_if_req->mask = mask;
	dp_if_req->opt = eDP_IF_METHOD_GET_LINK_STATUS;
	str_safe_cpy(dp_if_req->name, name, DP_IF_NAMESIZE - 1);

	rsp = NULL;
	rsp_size = 0;
	tmp = (void *)&rsp;
	ret = cmapi_require(session, 1, req, req_size, tmp, &rsp_size);
	free(req);
	if (rsp != NULL) {
		if (rsp->rsp_body_len != 0) {
			dp_rsp = (tcm_dp_rsp_body *) rsp->mod_rsp_body;
			dp_if_rsp = (tcm_dp_if_rsp_body *) dp_rsp->body;
			mask = dp_if_rsp->mask;
		}
		if (rsp->ret != eRET_SUCCESS) {
			ret = rsp->ret;
		}
		free(rsp);
	} else {
		memset(&mask, 0, sizeof(mask));
	}

	return (ret);

}

e_ret dp_if_do_getlinkstatus(tcm_session * session, const char *name, e_bool query, void **linkstatus)
{
	e_ret ret;
	tmask mask;
	int req_size;
	int rsp_size;
	int linkstatus_size;
	void **tmp;
	void *result;
	tcm_req_body *req;
	tcm_rsp_body *rsp;
	tcm_dp_req_body *dp_req;
	tcm_dp_rsp_body *dp_rsp;
	tcm_dp_if_req_body *dp_if_req;
	tcm_dp_if_rsp_body *dp_if_rsp;

	/* Set cancel and query to start scan. */
	memset(&mask, 0, sizeof(mask));
	if (query) {
		mask_set_bit(mask.mask[0], eWLAN_LINKSTAT_MASK0_QUERY);
	}

	req_size = sizeof(*req) + sizeof(*dp_req) + sizeof(*dp_if_req);
	req = malloc(req_size);
	if (req == NULL) {
		cmapi_error("malloc(%d) failed, err: %d,[%s]\n", req_size, errno, strerror(errno));
		return (eRET_NO_RESOURCE);
	}
	memset(req, 0, req_size);
	req->module = eCM_MODULE_DATA_PATH;
	req->req_body_len = sizeof(*dp_req) + sizeof(*dp_if_req);

	dp_req = (tcm_dp_req_body *) req->mod_req_body;
	dp_req->submod = eDP_SUB_MOD_DP_IF;
	dp_if_req = (tcm_dp_if_req_body *) dp_req->body;

	dp_if_req->mask = mask;
	dp_if_req->opt = eDP_IF_METHOD_GET_LINK_STATUS;
	str_safe_cpy(dp_if_req->name, name, DP_IF_NAMESIZE - 1);

	rsp = NULL;
	rsp_size = 0;
	tmp = (void *)&rsp;
	ret = cmapi_require(session, 1, req, req_size, tmp, &rsp_size);
	free(req);
	if (rsp != NULL) {
		if (rsp->rsp_body_len != 0) {
			dp_rsp = (tcm_dp_rsp_body *) rsp->mod_rsp_body;
			dp_if_rsp = (tcm_dp_if_rsp_body *) dp_rsp->body;
			mask = dp_if_rsp->mask;
			if (rsp->ret == eRET_SUCCESS) {
				linkstatus_size = rsp->rsp_body_len -
				    (sizeof(tcm_dp_rsp_body) + sizeof(tcm_dp_if_rsp_body));
				if (linkstatus_size > 0) {
					result = malloc(linkstatus_size);
					if (result == NULL) {
						cmapi_error("malloc(%d) failed, err: %d,[%s]\n",
							    linkstatus_size, errno, strerror(errno));
						*linkstatus = NULL;
						ret = eRET_NO_RESOURCE;
					} else {
						memcpy(result, dp_if_rsp->body, linkstatus_size);
						*linkstatus = result;
						ret = eRET_SUCCESS;
					}
				} else {
					*linkstatus = NULL;
					ret = eRET_SUCCESS;
				}
			}
		}
		if (rsp->ret != eRET_SUCCESS) {
			ret = rsp->ret;
		}
		free(rsp);
	} else {
		memset(&mask, 0, sizeof(mask));
	}

	return (ret);

}

e_ret dp_if_br_getlinkcfg(tcm_session * session, const char *name, void **linkcfg, int *linkcfg_size)
{
	return (dp_if_getlinkcfg(session, name, linkcfg, linkcfg_size));
}

e_ret dp_if_wlancli_getlinkcfg(tcm_session * session, const char *name, void **linkcfg, int *linkcfg_size)
{
	return (dp_if_getlinkcfg(session, name, linkcfg, linkcfg_size));
}

e_ret dp_if_wlanap_getlinkcfg(tcm_session * session, const char *name, void **linkcfg, int *linkcfg_size)
{
	return (dp_if_getlinkcfg(session, name, linkcfg, linkcfg_size));
}

e_ret dp_if_br_setlinkcfg(tcm_session * session, const char *name, tmask * mask, tbridge_if_linkcfg * linkcfg)
{
	return (dp_if_setlinkcfg(session, name, mask, linkcfg, sizeof(*linkcfg)));
}

e_ret dp_if_wlancli_setlinkcfg(tcm_session * session, const char *name, tmask * mask, twlan_cli_if_linkcfg * linkcfg)
{
	return (dp_if_setlinkcfg(session, name, mask, linkcfg, sizeof(*linkcfg)));
}

e_ret dp_if_wlanap_setlinkcfg(tcm_session * session, const char *name, tmask * mask, twlan_ap_if_linkcfg * linkcfg)
{
	return (dp_if_setlinkcfg(session, name, mask, linkcfg, sizeof(*linkcfg)));
}

e_ret dp_if_wlancli_start_scan_aps(tcm_session * session, const char *name)
{
	return (wlancli_do_scan_aps(session, name, eBOOL_TRUE));
}

e_ret dp_if_wlancli_stop_scan_aps(tcm_session * session, const char *name)
{
	return (wlancli_do_scan_aps(session, name, eBOOL_FALSE));
}

e_ret dp_if_wlancli_query_scan_aps(tcm_session * session, const char *name, twlan_cli_if_link_status ** aps)
{
	e_ret ret;
	twlan_cli_if_link_status *aps_list;

	ret = dp_if_do_getlinkstatus(session, name, eBOOL_TRUE, (void *)&aps_list);
	if (ret != eRET_SUCCESS) {
		cmapi_error("dp_if_do_getlinkstatus(%d) failed, ret: %d\n", eBOOL_TRUE, ret);
	} else {
		if (aps_list == NULL) {
			aps_list = malloc(sizeof(twlan_cli_if_link_status));
			if (aps_list == NULL) {
				cmapi_error("malloc(%d) failed, err: %d,[%s]\n",
					    (sizeof(twlan_cli_if_link_status)), errno, strerror(errno));
				*aps = NULL;
				ret = eRET_NO_RESOURCE;
			} else {
				aps_list->counter = 0;
				*aps = aps_list;
				ret = eRET_SUCCESS;
			}
		} else {
			*aps = aps_list;
		}
	}

	return (ret);
}

e_ret dp_if_wlancli_getlinkstatus(tcm_session * session, const char *name, twlan_cli_if_link_status ** aps)
{
	return (dp_if_do_getlinkstatus(session, name, eBOOL_FALSE, (void *)aps));
}

e_ret dp_if_wlanap_getlinkstatus(tcm_session * session, const char *name, twlan_ap_if_link_status ** clients)
{
	e_ret ret;
	twlan_ap_if_link_status *clis_list;

	*clients = NULL;
	ret = dp_if_do_getlinkstatus(session, name, eBOOL_FALSE, (void *)&clis_list);
	if (ret != eRET_SUCCESS) {
		cmapi_error("dp_if_do_getlinkstatus(%d) failed, ret: %d\n", eBOOL_FALSE, ret);
	} else {
		if (clis_list == NULL) {
			clis_list = malloc(sizeof(twlan_ap_if_link_status));
			if (clis_list == NULL) {
				cmapi_error("malloc(%d) failed, err: %d,[%s]\n",
					    (sizeof(twlan_ap_if_link_status)), errno, strerror(errno));
				*clients = NULL;
				ret = eRET_NO_RESOURCE;
			} else {
				clis_list->counter = 0;
				*clients = clis_list;
				ret = eRET_SUCCESS;
			}
		} else {
			*clients = clis_list;
		}
	}

	return (ret);

}

e_ret dp_if_ether_getlinkstatus(tcm_session * session, const char *name, teth_if_link_status ** status)
{
	return (dp_if_do_getlinkstatus(session, name, eBOOL_FALSE, (void *)status));
}

e_ret dp_cmn_opt_dev_optmode(tcm_session * session, unsigned char *mode, e_bool set)
{
	e_ret ret;
	int req_size;
	int rsp_size;
	void **tmp;
	tcm_req_body *req;
	tcm_rsp_body *rsp;
	tcm_dp_req_body *dp_req;
	tcm_dp_rsp_body *dp_rsp;
	tcm_dp_cmn_req_body *dp_cmn_req;
	tcm_dp_cmn_rsp_body *dp_cmn_rsp;

	req_size = sizeof(*req) + sizeof(*dp_req) + sizeof(*dp_cmn_req);
	req = malloc(req_size);
	if (req == NULL) {
		cmapi_error("malloc(%d) failed, err: %d,[%s]\n", req_size, errno, strerror(errno));
		return (eRET_NO_RESOURCE);
	}
	memset(req, 0, req_size);
	req->module = eCM_MODULE_DATA_PATH;
	req->req_body_len = sizeof(*dp_req) + sizeof(*dp_cmn_req);

	dp_req = (tcm_dp_req_body *) req->mod_req_body;
	dp_req->submod = eDP_SUB_MOD_DP_COMMON;
	dp_cmn_req = (tcm_dp_cmn_req_body *) dp_req->body;

	if (set) {
		dp_cmn_req->opt = eDP_CMN_OPT_SET_DP_MODE;
		dp_cmn_req->mode = *mode;
	} else {
		dp_cmn_req->opt = eDP_CMN_OPT_GET_DP_MODE;
	}

	rsp = NULL;
	rsp_size = 0;
	tmp = (void *)&rsp;
	ret = cmapi_require(session, 1, req, req_size, tmp, &rsp_size);
	free(req);
	if (rsp != NULL) {
		if (rsp->rsp_body_len != 0) {
			dp_rsp = (tcm_dp_rsp_body *) rsp->mod_rsp_body;
			dp_cmn_rsp = (tcm_dp_cmn_rsp_body *) dp_rsp->body;
			if (!set) {
				*mode = dp_cmn_rsp->mode;
			}
		}

		if (rsp->ret != eRET_SUCCESS) {
			ret = rsp->ret;
		}
		free(rsp);
	}

	return (ret);

}

e_ret dp_cmn_get_dev_optmode(tcm_session * session, unsigned char *mode)
{
	return (dp_cmn_opt_dev_optmode(session, mode, eBOOL_FALSE));
}

e_ret dp_cmn_set_dev_optmode(tcm_session * session, unsigned char mode)
{
	return (dp_cmn_opt_dev_optmode(session, &mode, eBOOL_TRUE));
}

e_ret dp_cmn_opt_dev_countryregion(tcm_session * session, unsigned int *country_num, e_bool set)
{
	e_ret ret;
	int req_size;
	int rsp_size;
	void **tmp;
	tcm_req_body *req;
	tcm_rsp_body *rsp;
	tcm_dp_req_body *dp_req;
	tcm_dp_rsp_body *dp_rsp;
	tcm_dp_cmn_req_body *dp_cmn_req;
	tcm_dp_cmn_rsp_body *dp_cmn_rsp;

	req_size = sizeof(*req) + sizeof(*dp_req) + sizeof(*dp_cmn_req);
	req = malloc(req_size);
	if (req == NULL) {
		cmapi_error("malloc(%d) failed, err: %d,[%s]\n", req_size, errno, strerror(errno));
		return (eRET_NO_RESOURCE);
	}
	memset(req, 0, req_size);
	req->module = eCM_MODULE_DATA_PATH;
	req->req_body_len = sizeof(*dp_req) + sizeof(*dp_cmn_req);

	dp_req = (tcm_dp_req_body *) req->mod_req_body;
	dp_req->submod = eDP_SUB_MOD_DP_COMMON;
	dp_cmn_req = (tcm_dp_cmn_req_body *) dp_req->body;

	if (set) {
		dp_cmn_req->opt = eDP_CMN_OPT_SET_COUNTRY;
		dp_cmn_req->country_number = *country_num;
	} else {
		dp_cmn_req->opt = eDP_CMN_OPT_GET_COUNTRY;
	}

	rsp = NULL;
	rsp_size = 0;
	tmp = (void *)&rsp;
	ret = cmapi_require(session, 1, req, req_size, tmp, &rsp_size);
	free(req);
	if (rsp != NULL) {
		if (rsp->rsp_body_len != 0) {
			dp_rsp = (tcm_dp_rsp_body *) rsp->mod_rsp_body;
			dp_cmn_rsp = (tcm_dp_cmn_rsp_body *) dp_rsp->body;
			if (!set) {
				*country_num = dp_cmn_rsp->country_number;
			}
		}

		if (rsp->ret != eRET_SUCCESS) {
			ret = rsp->ret;
		}
		free(rsp);
	}

	return (ret);

}

e_ret dp_cmn_set_dev_countryregion(tcm_session * session, unsigned int country_num)
{
	return (dp_cmn_opt_dev_countryregion(session, &country_num, eBOOL_TRUE));
}

e_ret dp_cmn_get_dev_countryregion(tcm_session * session, unsigned int *country_num)
{
	return (dp_cmn_opt_dev_countryregion(session, country_num, eBOOL_FALSE));
}

e_ret dp_cmn_get_dev_mac(tcm_session * session, tdevmac * devmac)
{
	e_ret ret;
	int req_size;
	int rsp_size;
	void **tmp;
	tcm_req_body *req;
	tcm_rsp_body *rsp;
	tcm_dp_req_body *dp_req;
	tcm_dp_rsp_body *dp_rsp;
	tcm_dp_cmn_req_body *dp_cmn_req;
	tcm_dp_cmn_rsp_body *dp_cmn_rsp;

	req_size = sizeof(*req) + sizeof(*dp_req) + sizeof(*dp_cmn_req);
	req = malloc(req_size);
	if (req == NULL) {
		cmapi_error("malloc(%d) failed, err: %d,[%s]\n", req_size, errno, strerror(errno));
		return (eRET_NO_RESOURCE);
	}
	memset(req, 0, req_size);
	req->module = eCM_MODULE_DATA_PATH;
	req->req_body_len = sizeof(*dp_req) + sizeof(*dp_cmn_req);

	dp_req = (tcm_dp_req_body *) req->mod_req_body;
	dp_req->submod = eDP_SUB_MOD_DP_COMMON;
	dp_cmn_req = (tcm_dp_cmn_req_body *) dp_req->body;

	dp_cmn_req->opt = eDP_CMN_OPT_GET_DEVMAC;

	rsp = NULL;
	rsp_size = 0;
	tmp = (void *)&rsp;
	ret = cmapi_require(session, 1, req, req_size, tmp, &rsp_size);
	free(req);
	if (rsp != NULL) {
		if (rsp->rsp_body_len != 0) {
			dp_rsp = (tcm_dp_rsp_body *) rsp->mod_rsp_body;
			dp_cmn_rsp = (tcm_dp_cmn_rsp_body *) dp_rsp->body;
			*devmac = dp_cmn_rsp->devmac;
		}

		if (rsp->ret != eRET_SUCCESS) {
			ret = rsp->ret;
		}
		free(rsp);
	}

	return (ret);
}
